﻿using KingsSharp.Common;
using KingsSharp.Common.Extensions;
using KingsSharp.Core;
using KingsSharp.Core.Data;
using CRM.Admin.Contracts.Contract.Sys;
using CRM.Admin.Contracts.Dto.Sys;
using CRM.Admin.Contracts.Model.Sys;
using System;
using System.Collections.Generic;
using System.Linq;
using KingsSharp.Common.Data;

namespace CRM.Admin.Services.Service.Sys
{
    public class UserInfoService : ServiceBase, IUserInfoService
    {
        /// <summary>
        /// 用户  Repository
        /// </summary>
        private IRepository<UserInfo, Guid> UserInfoRepository;

        /// <summary>
        /// 用户授权角色 Repository
        /// </summary>
        private IRepository<UserRole, Guid> UserRoleRepository;
        private IRepository<MenuNode, Guid> MenuNodeRepository;

        private IRepository<Authorization, Guid> AuthorizationRepository;

        public UserInfoService(IRepository<UserInfo, Guid> _UserInfoRepository, IRepository<UserRole, Guid> _UserRoleRepository
            , IRepository<Authorization, Guid> _AuthorizationRepository, IRepository<MenuNode, Guid> _MenuNodeRepository)
            : base(_UserInfoRepository.UnitOfWork)
        {
            this.UserInfoRepository = _UserInfoRepository;
            this.UserRoleRepository = _UserRoleRepository;
            this.AuthorizationRepository = _AuthorizationRepository;
            this.MenuNodeRepository = _MenuNodeRepository;
        }
        public IQueryable<Contracts.Model.Sys.UserInfo> ItemUserInfo
        {
            get { return UserInfoRepository.Entities; }
        }

        public KingsSharp.Common.Data.OperationResult InsertUserInfo(params Contracts.Dto.Sys.UserInfoDto[] dtos)
        {
            dtos.CheckNotNull("dtos");
            List<UserRoleDto> UserRoleDtos = new List<UserRoleDto>();
            UserInfoRepository.UnitOfWork.TransactionEnabled = true;
            var result= UserInfoRepository.Insert(dtos,(dto)=> {
                if(ItemUserInfo.Where(a=>a.LoginCode==dto.LoginCode).Count()>0)
                {
                    throw new Exception("登录名{0}已存在，请重新指定登陆名!".FormatWith(dto.LoginCode));
                }
            }, (dto, entity) => {
                UserRoleRepository.Delete(a => a.UserId == entity.Id);
                if (!string.IsNullOrWhiteSpace(dto.RoleIds))
                {
                    string[] roleIds = dto.RoleIds.Split(',');
                    for (int i = 0; i < roleIds.Length; i++)
                    {
                        UserRoleDto urdto = new UserRoleDto();
                        urdto.Id = Guid.NewGuid();
                        urdto.UserId = dto.Id;
                        urdto.RoleId = new Guid(roleIds[i]);
                        UserRoleDtos.Add(urdto);
                    }
                }
                return entity;
            });
            UserRoleRepository.Insert(UserRoleDtos);
            UserInfoRepository.UnitOfWork.SaveChanges();
            return result;
        }

        public KingsSharp.Common.Data.OperationResult UpdateUserInfo(params Contracts.Dto.Sys.UserInfoDto[] dtos)
        {
            dtos.CheckNotNull("dtos");
            List<UserRoleDto> UserRoleDtos = new List<UserRoleDto>();
            var result= UserInfoRepository.Update(dtos, (dto) =>
            {
                if (ItemUserInfo.Where(a => a.LoginCode == dto.LoginCode && a.Id != dto.Id).Count() > 0)
                {
                    throw new Exception("登录名{0}已存在，请重新指定登陆名!".FormatWith(dto.LoginCode));
                }
            }, (dto, entity) =>
            {
                var oldentity = UserInfoRepository.Entities.Where(a => a.Id == dto.Id).FirstOrDefault();
                entity.Password = oldentity.Password;
                UserRoleRepository.Delete(a => a.UserId == entity.Id);
                if (!string.IsNullOrWhiteSpace(dto.RoleIds))
                {
                    string[] roleIds = dto.RoleIds.Split(',');
                    for (int i = 0; i < roleIds.Length; i++)
                    {
                        UserRoleDto urdto = new UserRoleDto();
                        urdto.Id = Guid.NewGuid();
                        urdto.UserId = dto.Id;
                        urdto.RoleId = new Guid(roleIds[i]);
                        UserRoleDtos.Add(urdto);
                    }
                }
                return entity;
            });
            UserRoleRepository.Insert(UserRoleDtos);
            UserInfoRepository.UnitOfWork.SaveChanges();
            return result;
        }
        public OperationResult UpdateLastLoginData(UserInfoDto dto)
        {
            var user = UserInfoRepository.Entities.FirstOrDefault(s => s.Id == dto.Id);
            user.LastLoginDate = DateTime.Now;
            user.LastLoginIp = dto.LastLoginIp;
            user.Browser = dto.Browser;
            var i = UserInfoRepository.Update(user);
            if (i > 0)
            {
                return new OperationResult(OperationResultType.Success, "更新成功");
            }
            else
            {
                return new OperationResult(OperationResultType.Error, "更新失败");
            }
        }
        public KingsSharp.Common.Data.OperationResult DeleteUserInfo(params Guid[] ids)
        {
            ids.CheckNotNull("ids");
            var entitys = UserInfoRepository.Entities.Where(a => ids.Contains(a.Id)).ToList();
            entitys.ForEach(a => a.IsDeleted = true);
            int result = UserInfoRepository.Update(entitys.ToArray());
            return new KingsSharp.Common.Data.OperationResult(KingsSharp.Common.Data.OperationResultType.Success, "删除成功");
        }
        public OperationResult UpdateUserPwd(UserInfo user)
        {
            user.CheckNotNull("dto");
            var result = UserInfoRepository.Update(user);
            return new OperationResult(OperationResultType.Success,"修改成功");
          
        }
        public List<Guid> GetUserMenuCatalogs(Guid userid)
        {
            List<Guid> menus = new List<Guid>();
            var roleIds = UserRoleRepository.Entities.Where(a => a.UserId == userid).Select(s => s.RoleId).ToArray();
            if (roleIds == null)
            {
                return menus;
            }
            var nodeIds = AuthorizationRepository.Entities.
                Where(s => roleIds.Contains(s.RoleId)).Select(s => s.MenuNodeId).ToList();

            return nodeIds;
        }

        /// <summary>
        /// 判断用户是否具备某个页面的按钮权限
        /// </summary>
        /// <returns></returns>
        public bool GetUserForPageGarent(string actionName, string controllerName, string operaName, Guid userId)
        {
            var menuNode =
                MenuNodeRepository.Entities.FirstOrDefault(a => a.Action == actionName && a.Controller == controllerName);

            if (menuNode != null)
            {
                var auths = UserRoleRepository.Entities.
                     Where(a => a.UserId == userId && a.Role.Auths.Any(ms => ms.MenuNodeId == menuNode.Id)).Select(s => s.Role.Auths).ToArray();
                return auths.Any(item => item.Any(s => s.ActionCodes.Contains(operaName)));
            }
            return false;
        }
    }
}
